package com.songlanyun.modules.comment.service.impl;

import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.system.UserInfo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.songlanyun.common.enums.CommentConstant;
import com.songlanyun.common.enums.OrderConstant;
import com.songlanyun.common.exception.RRException;
import com.songlanyun.common.utils.BeanUtil;
import com.songlanyun.modules.account.entity.AccountEntity;
import com.songlanyun.modules.account.entity.UserInfoEntity;
import com.songlanyun.modules.account.model.vo.AccountVO;
import com.songlanyun.modules.account.service.AccountService;
import com.songlanyun.modules.account.service.UserInfoService;
import com.songlanyun.modules.comment.dao.OrderGoodsCommentDao;
import com.songlanyun.modules.comment.entity.OrderGoodsComment;
import com.songlanyun.modules.comment.entity.OrderGoodsCommentReply;
import com.songlanyun.modules.comment.model.dto.OrderGoodsCommentDTO;
import com.songlanyun.modules.comment.model.vo.OrderGoodsCommentVO;
import com.songlanyun.modules.comment.service.OrderGoodsCommentReplyService;
import com.songlanyun.modules.comment.service.OrderGoodsCommentService;
import com.songlanyun.modules.exception.MemberException;
import com.songlanyun.modules.goods.entity.Goods;
import com.songlanyun.modules.goods.service.GoodsService;
import com.songlanyun.modules.offlineorder.entity.OfflineOrder;
import com.songlanyun.modules.offlineorder.service.OfflineOrderService;
import com.songlanyun.modules.order.entity.ChildOrder;
import com.songlanyun.modules.order.service.ChildOrderService;
import com.songlanyun.modules.servicegoods.entity.ServiceGoods;
import com.songlanyun.modules.servicegoods.service.ServiceGoodsService;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.songlanyun.common.utils.PageUtils;
import com.songlanyun.common.utils.Query;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;


@Service("orderGoodsCommentService")
public class OrderGoodsCommentServiceImpl extends ServiceImpl<OrderGoodsCommentDao, OrderGoodsComment> implements OrderGoodsCommentService {

    @Resource
    private GoodsService goodsService;

    @Resource
    private ServiceGoodsService serviceGoodsService;

    @Resource
    private OrderGoodsCommentReplyService orderGoodsCommentReplyService;

    @Resource
    private ChildOrderService childOrderService;

    @Resource
    private AccountService accountService;

    @Resource
    private UserInfoService userInfoService;

    @Resource
    private OfflineOrderService offlineOrderService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        Long userId = MapUtil.getLong(params, "user_id");
        Long shopId = MapUtil.getLong(params, "shop_id");
        Long goodsId = MapUtil.getLong(params, "goods_id");
        Long orderId = MapUtil.getLong(params, "order_id");
        Integer type = MapUtil.getInt(params, "type");
        Integer level = MapUtil.getInt(params, "level");

        IPage<OrderGoodsComment> page = this.page(
                new Query<OrderGoodsComment>().getPage(params),
                new LambdaQueryWrapper<OrderGoodsComment>()
                        .eq(userId != null, OrderGoodsComment::getUserId, userId)
                        .eq(shopId != null, OrderGoodsComment::getShopId, shopId)
                        .eq(goodsId != null, OrderGoodsComment::getGoodsId, goodsId)
                        .eq(orderId != null, OrderGoodsComment::getOrderId, orderId)
                        .eq(level != null, OrderGoodsComment::getLevel, level)
                        .eq(type != null, OrderGoodsComment::getType, type)
                        .orderByDesc(OrderGoodsComment::getCreateTime)
        );

        setReply(page.getRecords());//设置商家回复

        return new PageUtils(page);
    }

    @Override
    public OrderGoodsComment getById(Long id, boolean isThrow) {
        OrderGoodsComment comment = this.baseMapper.selectById(id);
        if (comment == null) {
            if (isThrow) {
                throw new RRException(MemberException.COMMENT_NOT_EXISTS);
            }
        }
        return comment;
    }


    @Override
    public void saveComment(OrderGoodsCommentDTO dto) {
        OrderGoodsComment orderGoodsComment = new OrderGoodsComment();
        BeanUtil.copyPropertiesIgnoreNull(dto, orderGoodsComment);
        orderGoodsComment.setType(CommentConstant.CommentType.getByCode(dto.getType()));
        Long shopId;
        switch (orderGoodsComment.getType()) {
            case GENERAL:
                Goods goods = goodsService.getById(orderGoodsComment.getGoodsId(), true);
                shopId = goods.getShopId();
                break;
            case SERVICE:
                ServiceGoods serviceGoods = serviceGoodsService.loadServiceGoodsById(orderGoodsComment.getGoodsId(), true);
                shopId = serviceGoods.getShopId();
                break;
            default:
                return;
        }

        //查询商家id
        orderGoodsComment.setShopId(shopId);//设置商家id

        this.baseMapper.insert(orderGoodsComment);

        //改变子订单的评论状态
        ChildOrder childOrder = childOrderService.loadByOrderAndChildId(dto.getOrderId(), dto.getChlidOrderId(), true);
        childOrder.setCommentStatus(OrderConstant.CommentStatus.COMPLETE);
        childOrder.setFactCommentTime(System.currentTimeMillis());
        childOrderService.modify(childOrder);

        //改变主订单的评论状态
        childOrderService.commentChildOrderSync(childOrder);

    }

    @Override
    public List<OrderGoodsComment> getMemberComments(Map<String, Object> params) {
        Long userId = MapUtil.getLong(params, "user_id");
        Long shopId = MapUtil.getLong(params, "shop_id");
        Long goodsId = MapUtil.getLong(params, "goods_id");
        Long orderId = MapUtil.getLong(params, "order_id");
        Integer type = MapUtil.getInt(params, "type");

        List<OrderGoodsComment> orderGoodsComments = this.baseMapper.selectList(
                new LambdaQueryWrapper<OrderGoodsComment>()
                        .eq(OrderGoodsComment::getShow, true)
                        .eq(userId != null, OrderGoodsComment::getUserId, userId)
                        .eq(shopId != null, OrderGoodsComment::getShopId, shopId)
                        .eq(goodsId != null, OrderGoodsComment::getGoodsId, goodsId)
                        .eq(orderId != null, OrderGoodsComment::getOrderId, orderId)
                        .eq(type != null, OrderGoodsComment::getType, type)
                        .orderByDesc(OrderGoodsComment::getCreateTime)
        );

        setReply(orderGoodsComments);//设置商家回复

        return orderGoodsComments;

    }

    @Override
    public List<OrderGoodsCommentVO> getAvgByGoods() {
        return this.baseMapper.getAvgByGoods();
    }

    @Override
    public List<OrderGoodsCommentVO> getAvgByShop() {
        return this.baseMapper.getAvgByShop();
    }

    /**
     * 统计商品评价
     *
     * @param userId
     * @param shopId
     * @return
     */
    @Override
    public Integer goodsEvaluateNum(Long userId, Long shopId, CommentConstant.CommentType type) {
        //商家登录，查询会员评价此商家商品的所有评价数
        //平台登录，查询所有评价数
        return this.baseMapper.selectCount(
                new LambdaQueryWrapper<OrderGoodsComment>()
                        .eq(OrderGoodsComment::getUserId, userId)
                        .eq(OrderGoodsComment::getType, type)
                        .eq(shopId == null || shopId != 0, OrderGoodsComment::getShopId, shopId)
        );

    }

    @Override
    public PageUtils queryCommentPage(Map<String, Object> params) {
        //分页数据
        IPage<OrderGoodsComment> page = this.baseMapper.queryCommentPage(new Query<OrderGoodsComment>().getPage(params), params);
        page.getRecords().forEach(OrderGoodsComment::loadIsReply);
        return new PageUtils(page);
    }

    @Override
    public OrderGoodsComment getApiById(Long id) {
        return this.baseMapper.selectById(
                new LambdaQueryWrapper<OrderGoodsComment>()
                        .eq(OrderGoodsComment::getId, id)
                        .eq(OrderGoodsComment::getShow, true)
        );
    }

    @Override
    public void modelDel(CommentConstant.CommentType type, Long goodsId) {
        this.update(
                new LambdaUpdateWrapper<OrderGoodsComment>()
                        .eq(OrderGoodsComment::getType, type)
                        .eq(OrderGoodsComment::getGoodsId, goodsId)
        );
    }

    @Override
    public OrderGoodsComment getMemberComments(CommentConstant.CommentType type, Long userId, String orderId) {
        return this.baseMapper.selectOne(
                new LambdaQueryWrapper<OrderGoodsComment>()
                        .eq(OrderGoodsComment::getShow, true)
                        .eq(OrderGoodsComment::getUserId, userId)
                        .eq(OrderGoodsComment::getOrderId, orderId)
                        .eq(OrderGoodsComment::getType, type)
                        .last("limit 1")
        );
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void commentUnionBusiness(OrderGoodsCommentDTO dto) {
        Integer count = this.lambdaQuery()
                .eq(OrderGoodsComment::getUserId, dto.getUserId())
                .eq(OrderGoodsComment::getOrderId, dto.getOrderId()).count();
        if (count > 0) {
            throw new RRException("该订单已评价，请勿重复评价");
        }

        OrderGoodsComment orderGoodsComment = new OrderGoodsComment();
        BeanUtil.copyPropertiesIgnoreNull(dto, orderGoodsComment);
        orderGoodsComment.setType(CommentConstant.CommentType.UNION_BUSINESS);

        OfflineOrder offlineOrder = offlineOrderService.getById(orderGoodsComment.getOrderId());
        if (ObjectUtil.isNull(offlineOrder)) {
            throw new RRException("订单不存在");
        }
        orderGoodsComment.setShopId(offlineOrder.getShopId());
        this.baseMapper.insert(orderGoodsComment);

        //修改订单评论状态
        offlineOrder.setComment(true);
        offlineOrderService.updateById(offlineOrder);

    }


    /**
     * 设置商家回复
     *
     * @param commentList
     * @return
     */
    private List<OrderGoodsComment> setReply(List<OrderGoodsComment> commentList) {
        commentList.forEach(o -> {
            List<OrderGoodsCommentReply> list = orderGoodsCommentReplyService.list(
                    new LambdaQueryWrapper<OrderGoodsCommentReply>()
                            .eq(OrderGoodsCommentReply::getCommentId, o.getId())
            );
            o.setReplyList(list);
            //设置用户名和手机号
            UserInfoEntity userInfoEntity = userInfoService.loadById(o.getUserId(), true);
            o.setNickname(userInfoEntity.loadResRealName());//d昵称
            o.setHeadPhoto(userInfoEntity.getHeadPhoto());//头像
            o.setMobile(accountService.getMobileByUserId(o.getUserId()));
            //设置商品信息
//            Goods goods = goodsService.getById(o.getGoodsId(), false);
//            o.setGoods(goods);
        });

        return commentList;
    }

}
